package inutan.gateway.action;

import bright.serialization.ByteBuf;
import inutan.common.constant.DataConstant;
import inutan.common.context.FlowContext;
import inutan.gateway.external.ExternalKit;
import inutan.common.inner.protocol.InnerMessage;
import inutan.gateway.external.GamePack;
import luban.common.LongValue;
import luban.room.ChangeRoomUserState;
import luban.user.BizCountOnline;
import inutan.gateway.session.user.UserSession;
import inutan.gateway.session.user.UserSessions;
import luban.common.Command;
import org.ricks.common.lang.Logger;
import org.ricks.ioc.anno.Action;
import org.ricks.ioc.anno.ActionMethod;
import org.ricks.net.AioSession;
import org.ricks.net.DataCodecKit;
import org.ricks.net.DefaultPacket;
import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicLong;


/**
 * @author ：demon-chen
 * 来自业务集群的消息 使用自定义消息体
 *
 * 网关 -> 业务节点 -> 网关 使用RPC调用
 * 网关需要收到业务节点返回结果
 */
@Action
public class GatewayController {

    private static final AtomicLong l = new AtomicLong();


    @ActionMethod(cmd = Command.LoginSuccess)
    public void loginSuccess(FlowContext<DefaultPacket> context) {
        DefaultPacket defaultPacket = context.getPacket();
        LongValue userId = LongValue.deserializeLongValue(new ByteBuf(defaultPacket.getPacket()));
        Logger.info("userId: "+userId+"  login success & start bind sessionId:"+context.getSession().sid());
        /**  userSessionId <-> userId 绑定成功才是登录成功,只有绑定成功才能多人广播 */
        UserSessions.me().settingUserId(context.getUserSessionId(),userId.value);
    }


    /**
     * 5s同步一次 在线人数方式
     * @param context
     */
    @ActionMethod(cmd = Command.SyncBizOnlineCount)
    public void syncBizOnlineCount(FlowContext<DefaultPacket> context) {
        DefaultPacket defaultPacket = context.getPacket();
        BizCountOnline bizCountOnline = DataCodecKit.decode(defaultPacket.getPacket(), BizCountOnline.class);
//        LogicSessions.me().changeBitOnline(bizCountOnline);


    }

//    /**
//     * 游戏服通知网关节点，有玩家登录游戏节点
//     * @param context
//     */
//    public void userIntoGame(GameFlowContext context) {
//        UserOnlineCountLoadBalancer.getInstance().userIntoGame(context.getSession());
//    }
//
//    /**
//     * 游戏服通知网关节点，有玩家退出游戏节点
//     * @param context
//     */
//    public void userQuitGame(GameFlowContext context) {
//        UserOnlineCountLoadBalancer.getInstance().userQuitGame(context.getSession());
//    }

    /**
     * rpc 方式
     * @param context
     */
    @ActionMethod(cmd = Command.CreateRoom)
    public void createRoom(FlowContext context) {
//        LoginBroker loginBroker = DataCodecKit.decode(context.packet(), LoginBroker.class);
//        Logger.info("userId:"+context.getUserId()+" create room:"+context.getGroupId()+" .join success ");
//        UserSession userSession = UserSessions.me().getUserSessionByUserId(context.getUserId());
//        UserSessions.me().join(context.getGroupId(),userSession);
    }

    @ActionMethod(cmd = 10001)
    public void test(FlowContext context) {
        long count = l.getAndIncrement();
        if(count % 100000 == 0) {
            Logger.info("收到机器人消息 userId:"+Thread.currentThread().getName()+" enter room.................................  packId:" + context.getPackageId() + ", count:" + count);
        }
        InnerMessage message = ExternalKit.createInnerMessage((short) 10001);
        message.state = DataConstant.RUTE_MESSAGE;
        message.userSessionId = context.getUserSessionId();
        message.packageId = context.getPackageId();

        GamePack gamePack = ExternalKit.convertNetPack(message);
        int headLength = 2 + 4 + 2;
        //游戏默认是小端
        ByteBuffer byteBuffer = ByteBuffer.allocate(headLength + gamePack.packet().length);
        byteBuffer.putShort(gamePack.cmd());
        byteBuffer.putInt(gamePack.getPackageId());
        byteBuffer.putShort(gamePack.responseStatus);
        byteBuffer.put(gamePack.packet());
        byteBuffer.flip();//重置 limit 和postion 值 否则 buffer 读取数据不对
        byte[] bytes = new byte[headLength + gamePack.packet().length];
        byteBuffer.get(bytes);
//            System.err.println("发送 字节长度：" + bytes.length + " & " + bytes[0] + "," + bytes[1]);
        AioSession session = context.getSession();
        session.send(bytes);
    }

    @ActionMethod(cmd = Command.ChangeRoomUserState)
    public void changeRoomUserState(FlowContext<DefaultPacket> context) {
        DefaultPacket defaultPacket = context.getPacket();
        ChangeRoomUserState changeRoomUserState = ChangeRoomUserState.deserializeChangeRoomUserState(new ByteBuf(defaultPacket.getPacket()));
        Logger.info("userId:"+context.getUserId()+" change room:"+changeRoomUserState.roomId+" . isBind:" + changeRoomUserState.isBind);
        if(changeRoomUserState.isBind) {
            enterRoom(context.getUserId(), changeRoomUserState.roomId);
            return;
        }
        exitRoom(context.getUserId(), changeRoomUserState.roomId);
    }

    public void enterRoom(long userId, String roomId) {
        Logger.info("userId:{} exit room:{} .join success ",userId, roomId);
        UserSession userSession = UserSessions.me().getUserSessionByUserId(userId);
        UserSessions.me().join(roomId, userSession);
    }

    public void exitRoom(long userId, String roomId) {
        Logger.info("userId:{} exit room:{} .join success ",userId, roomId);
        UserSession userSession = UserSessions.me().getUserSessionByUserId(userId);
        UserSessions.me().remove(userSession);
    }

//    /**
//    * @Explain --> GM增加网关节点 通知到所有业务节点
//    * @Author yanwang
//    * @Date 2023/5/10 10:24
//    **/
//    @ActionMethod(cmd = Command.AddBroker)
//    public void addBroker(GameFlowContext context){
//        InnerMessage message = ExternalKit.createInnerMessage( context.cmd(),context.packet());
////        LogicSessions.me().broadcastAll(message);
//    }

}
